<?php


namespace app\index\controller;
use app\BaseController;

//本控制器用于测试操作数据库-查询构造器
class Db extends BaseController
{
    //database.php配置中可以配置各种数据库
    //type	    数据库
    //mysql	    MySQL
    //sqlite	SqLite
    //pgsql	    PostgreSQL
    //sqlsrv	SqlServer
    //mongo	    MongoDb
    //oracle	Oracle
    public function index()
    {
        // 开启读写分离后，强制查询主库
        //Db::name('user')
        //    ->where('id', 1)
        //    ->update(['name' => 'thinkphp']);
        //Db::name('user')
        //    ->master(true)
        //    ->find(1);

        // ——————————查询构造器——————————
        // ########## 查询
        // 查一条数据，如果无条件则不返回任何结果
        //Db::table('think_user')->where('id', 1)->find(); 不存在则返回null
        //Db::table('think_user')->where('id', 1)->findOrEmpty(); 不存在则返回空数组
        //Db::table('think_user')->where('id', 1)->findOrFail(); 不存在则抛出异常
        // 查多条数据
        //Db::table('think_user')->where('status', 1)->select(); 返回数据集对象
        //Db::table('think_user')->where('status', 1)->select()->toArray(); 返回数组
        //Db::table('think_user')->where('status',1)->selectOrFail(); 不存在则抛出异常
        // 返回某个字段的值
        //Db::table('think_user')->where('id', 1)->value('name');
        // 返回数组
        //Db::table('think_user')->where('status',1)->column('name');
        // 指定id字段的值作为索引
        //Db::table('think_user')->where('status',1)->column('name', 'id');
        // 指定id字段的值作为索引 返回所有数据
        //Db::table('think_user')->where('status',1)->column('*','id');
        // 分批处理，如每次处理100个数据
        //Db::table('think_user')->where('score','>',20)->chunk(100, function($users) {
        //    foreach ($users as $user) {
        //        // 处理结果集...
        //		if($user->status==0){
        //            return false; 终止对后续数据处理
        //        }
        //    }
        //},'create_time', 'desc'); 这里指定按照时间倒序进行处理，默认为主键
        //处理大量数据时推荐使用游标
        //cursor方法返回的是一个生成器对象，user变量是数据表的一条数据（数组）。
        //$cursor = Db::table('user')->where('status', 1)->cursor();
        //foreach($cursor as $user){
        //	echo $user['name'];
        //}

        // ########## 查询表达式
        //where('字段名','查询表达式','查询条件');
        //表达式	            含义	                    快捷查询方法
        //=	                等于
        //<>	            不等于
        //>	                大于
        //>=	            大于等于
        //<	                小于
        //<=	            小于等于
        //[NOT] LIKE	    模糊查询	                whereLike/whereNotLike
        //[NOT] BETWEEN	    （不在）区间查询	        whereBetween/whereNotBetween
        //[NOT] IN	        （不在）IN 查询	        whereIn/whereNotIn
        //[NOT] NULL	    查询字段是否（不）是NULL	whereNull/whereNotNull
        //[NOT] EXISTS	    EXISTS查询	            whereExists/whereNotExists
        //[NOT] REGEXP	    正则（不）匹配查询（仅支持Mysql）
        //[NOT] BETWEEN     TIME	时间区间比较	    whereBetweenTime
        //> TIME	        大于某个时间	            whereTime
        //< TIME	        小于某个时间	            whereTime
        //>= TIME	        大于等于某个时间	        whereTime
        //<= TIME	        小于等于某个时间	        whereTime
        //EXP	            表达式查询，支持SQL语法   	whereExp
        //find in set	    FIND_IN_SET查询	        whereFindInSet

        //Db::name('user')->where('name', 'like', ['%think','php%'],'OR')->select();
        //SELECT * FROM `think_user` WHERE  (`name` LIKE '%think' OR `name` LIKE 'php%')

        //Db::name('user')->whereLike('name','thinkphp%')->select();
        //Db::name('user')->whereNotLike('name','thinkphp%')->select();

        //Db::name('user')->where('id','between','1,8')->select();
        //Db::name('user')->whereBetween('id','1,8')->select();

        //Db::name('user')->where('id','in','1,3,8')->select();
        //可以改成：
        //Db::name('user')->where('id','exp',' IN (1,3,8) ')->select();


        // ########## 插入
        // 新增一条
        //$data = ['foo' => 'bar', 'bar' => 'foo'];
        //Db::name('user')->save($data);
        //Db::name('user')->insert($data); 返回成功条数
        //Db::name('user')->strict(false)->insert($data); 忽略异常，抛弃不存在的字段
        //$userId = Db::name('user')->insertGetId($data); 返回新增后数据的自增主键

        //新增多条
        //$data = [
        //    ['foo' => 'bar', 'bar' => 'foo'],
        //    ['foo' => 'bar1', 'bar' => 'foo1'],
        //    ['foo' => 'bar2', 'bar' => 'foo2']
        //];
        //Db::name('user')->limit(100)->insertAll($data); 分批插入，并且每次最多100条

        // ########## 更新
        //Db::name('user')->save(['id' => 1, 'name' => 'thinkphp']);
        //Db::name('user')->where('id', 1)->update(['name' => 'thinkphp']);
        //Db::name('user') ->where('id', 1)->data(['name' => 'thinkphp'])->update();

        //Db::name('user') 使用name方法需要设置表前缀
        //    ->where('id',1)
        //    ->exp('name','UPPER(name)') 使用SQL函数
        //    ->update();
        //相当于执行了UPDATE `think_user`  SET `name` = UPPER(name)  WHERE  `id` = 1

        //Db::name('user')
        //    ->where('id', 1)
        //    ->update([
        //        'name'		=>	Db::raw('UPPER(name)'),
        //        'score'		=>	Db::raw('score-3'),
        //        'read_time'	=>	Db::raw('read_time+1')
        //    ]);

        //// score 字段加 1
        //Db::table('think_user')
        //    ->where('id', 1)
        //    ->inc('score')
        //    ->update();
        //
        //// score 字段加 5
        //Db::table('think_user')
        //    ->where('id', 1)
        //    ->inc('score', 5)
        //    ->update();
        //
        //// score 字段减 1
        //Db::table('think_user')
        //    ->where('id', 1)
        //    ->dec('score')
        //    ->update();
        //
        //// score 字段减 5
        //Db::table('think_user')
        //    ->where('id', 1)
        //    ->dec('score', 5)
        //    ->update();

        // ########## 删除
        // 根据主键删除
        //Db::table('think_user')->delete(1);
        //Db::table('think_user')->delete([1,2,3]);
        // 条件删除
        //Db::table('think_user')->where('id',1)->delete();
        //Db::table('think_user')->where('id','<',10)->delete();
        // 无条件删除所有数据
        //Db::name('user')->delete(true);

        // 软删除数据 使用delete_time字段标记删除
        //Db::name('user')
        //	->where('id', 1)
        //	->useSoftDelete('delete_time',time())
        //    ->delete();

        //########## 查询事件（数据库操作的回调）
        //事件	        描述
        //before_select	select查询前回调
        //before_find	find查询前回调
        //after_insert	insert操作成功后回调
        //after_update	update操作成功后回调
        //after_delete	delete操作成功后回调

        //注册一个查询事件
        //\think\facade\Db::event('before_select', function ($query) {
        //    // 事件处理
        //    // 在这里可以对$query进行操作
        //    $query->where('site_id',1)->order('update_time desc');
        //
        //    $model = $query->getModel();        // 实例化的模型对象,可以给模型自定义一些属性,在这里读取,相当于传参.
        //});

        //########## 获取器
        //$a = Db::name('user')->withAttr('status',function ($name,$data){ //第一个参数$name是当前字段的值，第二个参数$data是所有的数据。
        //$value = $name?'正常':'禁用';
        //return strtolower($value);
        //})->select()->toArray();
        //
        //halt($a);
        //
        //如果使用模型，就在模型定义
        //getStatusAttr ： get+字段名+Attr 就不需要这个了 withAttr

        //########## 事务操作
        //注意在事务操作的时候，确保数据库连接使用的是同一个，特别是读写分离开启后。
        //自动控制事务
        //Db::transaction(function () { //闭包中如果发生异常自动回滚
        //    Db::table('think_user')->find(1);
        //    Db::table('think_user')->delete(1);
        //});

        //手动控制事务
        //// 启动事务
        //Db::startTrans();
        //try {
        //    Db::table('think_user')->find(1);
        //    Db::table('think_user')->delete(1);
        //    // 提交事务
        //    Db::commit();
        //} catch (\Exception $e) {
        //    // 回滚事务
        //    Db::rollback();
        //}

        //XA事务（分布式事务）
        //Db::transactionXa(function () {
        //    Db::connect('db1')->table('think_user')->delete(1);
        //    Db::connect('db2')->table('think_user')->delete(1);
        //}, [Db::connect('db1'),Db::connect('db2')]);
        //要确保你的数据表引擎为InnoDB，并且开启XA事务支持。

        //########## 数据集
        //// 获取数据集
        //$users = Db::name('user')->select();
        //// 遍历数据集
        //foreach($users as $user){
        //    echo $user['name'];
        //    echo $user['id'];
        //}

        //方法	            描述
        //isEmpty	        是否为空
        //toArray	        转换为数组
        //all	            所有数据
        //merge	            合并其它数据
        //diff	            比较数组，返回差集
        //flip	            交换数据中的键和值
        //intersect	        比较数组，返回交集
        //keys	            返回数据中的所有键名
        //pop	            删除数据中的最后一个元素
        //shift	            删除数据中的第一个元素
        //unshift	        在数据开头插入一个元素
        //push	            在结尾插入一个元素
        //reduce	        通过使用用户自定义函数，以字符串返回数组
        //reverse	        数据倒序重排
        //chunk	            数据分隔为多个数据块
        //each	            给数据的每个元素执行回调
        //filter	        用回调函数过滤数据中的元素
        //column	        返回数据中的指定列
        //sort	            对数据排序
        //order	            指定字段排序
        //shuffle	        将数据打乱
        //slice	            截取数据中的一部分
        //map	            用回调函数处理数组中的元素
        //where	            根据字段条件过滤数组中的元素
        //whereLike	        Like查询过滤元素
        //whereNotLike	    Not Like过滤元素
        //whereIn	        IN查询过滤数组中的元素
        //whereNotIn	    Not IN查询过滤数组中的元素
        //whereBetween	    Between查询过滤数组中的元素
        //whereNotBetween	Not Between查询过滤数组中的元素

        //$users = Db::name('user')->select();
        //if($users->isEmpty()){
        //    echo '数据集为空';
        //}

    }



}